


use crate::physical_plan::PhysicalPlanExprArg;
use crate::data_frame::DataInstance;
use crate::run_plan::{HandResult};
use crate::lazy_static::__Deref;

/*
    获取一组数据的第一个的某一个元素
*/
pub fn first(args: &[Box<PhysicalPlanExprArg>], data: DataInstance) -> HandResult {
    if args.len() != 1{
        return HandResult::Err(());
    }

    let element = &args[0];
    match element.deref(){
        PhysicalPlanExprArg::RealValue(_) => {return HandResult::Err(());},
        PhysicalPlanExprArg::ConfValue(_) => {return HandResult::Err(());},
        PhysicalPlanExprArg::ElementValue(element) => {
            match data{
                DataInstance::BatchData(_) => {return HandResult::Err(());},
                DataInstance::GroupData(group_data) => {
                    if let Some(first) = group_data.data.first(){
                        return first.data.get_key_value(element);
                    }else{
                        return HandResult::Err(());
                    }
                },
            }
        },
    }
}

pub fn last(args: &[Box<PhysicalPlanExprArg>], data: DataInstance) -> HandResult {
    if args.len() != 1{
        return HandResult::Err(());
    }

    let element = &args[0];
    match element.deref(){
        PhysicalPlanExprArg::RealValue(_) => {return HandResult::Err(());},
        PhysicalPlanExprArg::ConfValue(_) => {return HandResult::Err(());},
        PhysicalPlanExprArg::ElementValue(element) => {
            match data{
                DataInstance::BatchData(_) => {return HandResult::Err(());},
                DataInstance::GroupData(group_data) => {
                    if let Some(first) = group_data.data.last(){
                        return first.data.get_key_value(element);
                    }else{
                        return HandResult::Err(());
                    }
                },
            }
        },
    }
}

pub fn take_nth(args: &[Box<PhysicalPlanExprArg>], data: DataInstance) -> HandResult {
    if args.len() != 2{
        return HandResult::Err(());
    }

    let element = &args[0];
    let nth = &args[1];

    match element.deref(){
        PhysicalPlanExprArg::RealValue(_) => {return HandResult::Err(());},
        PhysicalPlanExprArg::ConfValue(_) => {return HandResult::Err(());},
        PhysicalPlanExprArg::ElementValue(element) => {
            if let PhysicalPlanExprArg::ConfValue(nth) = nth.deref(){
                let nth = nth.try_u64()?;

                match data{
                    DataInstance::BatchData(_) => {return HandResult::Err(());},
                    DataInstance::GroupData(group_data) => {
                        if let Some(nth) = group_data.data.take_nth(nth as usize){
                            return nth.data.get_key_value(element);
                        }else{
                            return HandResult::Err(());
                        }
                    },
                }
            }else{
                return HandResult::Err(());
            }
        },
    }
}

